/**
 * 
 */
package xalan.filesearch.service;

import java.util.HashSet;
import java.util.Set;
import xalan.filesearch.model.Catalogue;
import xalan.filesearch.model.FileDesc;
import xalan.filesearch.model.Tag;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;


import xalan.xml.DeserializationTemplate;
import xalan.xml.SerializationTemplate;
import xalan.xml.XMLUtils;

/** 
 * <!-- begin-UML-doc -->
 * <!-- end-UML-doc -->
 * @author Piotrek
 * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
 */
public class XMLMarshaller {
	public static final String NAME_ATTRIBUTE = "NAME";
	public static final String DESCRIPTION_ELEMENT = "DESCRIPTION";
	public static final String PATH_ELEMENT = "PATH";
	public static final String TAG_ELEMENT = "TAG";
	public static final String FILE_ELEMENT = "FILE";
	public static final String CATALOG_ELEMENT = "CATALOG";
	public static final String CATALOGS_ELEMENT = "CATALOGS";
	
	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
	 */
	private String fileName;

	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @return
	 * @generated "UML to Java (com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform)"
	 */
	public Set<Catalogue> deserialize() {
		// begin-user-code
		final Set<Catalogue> catalogues = new HashSet<Catalogue>();
		
		DeserializationTemplate template = new DeserializationTemplate() {
			
			@Override
			protected void deserializeFromXML(Document document) {
				Element cataloguesElement = document.getDocumentElement();
				NodeList cataloguesList = cataloguesElement.getElementsByTagName(CATALOG_ELEMENT);
				for(int i=0;i<cataloguesList.getLength();++i) {
					Element e = (Element)cataloguesList.item(i);
					if(e.getTagName().equals(CATALOG_ELEMENT)) {
						catalogues.add(deserializeCatalogue(e));
					}
				}
			}
		};
		
		template.deserialize(fileName);
		
		return catalogues;
		// end-user-code
	}

	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @param catalogues
	 */
	public void serialize(final Set<Catalogue> catalogues) {
		// begin-user-code
		SerializationTemplate template = new SerializationTemplate() {
			@Override
			protected Element buildRootElement(Document document) {
				Element catalogsElement = document.createElement(CATALOGS_ELEMENT);
				
				for(Catalogue c: catalogues) {
					catalogsElement.appendChild(serializeCatalogue(document, c));
				}
				
				return catalogsElement;
			}
		};
		
		template.serializeToXml(fileName);
		// end-user-code
	}

	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @param catalogue
	 */
	protected Element serializeCatalogue(Document document, Catalogue catalogue) {
		// begin-user-code
		Element catalogElement = document.createElement(CATALOG_ELEMENT);
		
		Element pathElement = document.createElement(PATH_ELEMENT);
		pathElement.setTextContent(catalogue.getPath());
		catalogElement.appendChild(pathElement);
		
		Element descElement = document.createElement(DESCRIPTION_ELEMENT);
		descElement.setTextContent(catalogue.getDescription());
		catalogElement.appendChild(descElement);
		
		for(FileDesc f: catalogue.getFiles()) {
			catalogElement.appendChild(serializeFile(document, f));
		}
		
		return catalogElement;
		// end-user-code
	}

	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @param file
	 */
	protected Element serializeFile(Document document, FileDesc file) {
		// begin-user-code
		Element fileElement = document.createElement(FILE_ELEMENT);
		
		Element pathElement = document.createElement(PATH_ELEMENT);
		pathElement.setTextContent(file.getPath());
		fileElement.appendChild(pathElement);
		
		Element descElement = document.createElement(DESCRIPTION_ELEMENT);
		descElement.setTextContent(file.getDescription());
		fileElement.appendChild(descElement);
		
		for(Tag t: file.getTags()) {
			fileElement.appendChild(serializeTag(document, t));
		}
		
		return fileElement;
		// end-user-code
	}

	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @param tag
	 */
	protected Element serializeTag(Document document, Tag tag) {
		// begin-user-code
		Element tagElement = document.createElement(TAG_ELEMENT);
		tagElement.setAttribute(NAME_ATTRIBUTE, tag.getName());
		return tagElement;
		// end-user-code
	}

	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @param element
	 * @return
	 */
	protected Catalogue deserializeCatalogue(Element element) {
		// begin-user-code
		Catalogue catalogue = new Catalogue();
		
		catalogue.setPath(XMLUtils.getElementsText(element, PATH_ELEMENT));
		catalogue.setDescription(XMLUtils.getElementsText(element, PATH_ELEMENT));
		
		NodeList files = element.getElementsByTagName(FILE_ELEMENT);
		for(int i=0; i < files.getLength(); ++i) {
			Element fileElement = (Element)files.item(i);
			if(fileElement.getTagName().equals(FILE_ELEMENT)) {
				catalogue.add(deserializeFile(fileElement));
			}
		}
		
		return catalogue;
		// end-user-code
	}

	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @param object
	 * @return
	 */
	protected FileDesc deserializeFile(Element element) {
		// begin-user-code
		FileDesc file = new FileDesc();
		
		file.setPath(XMLUtils.getElementsText(element, PATH_ELEMENT));
		file.setDescription(XMLUtils.getElementsText(element, PATH_ELEMENT));
		
		NodeList tags = element.getElementsByTagName(TAG_ELEMENT);
		for(int i=0; i < tags.getLength(); ++i) {
			Element tagElement = (Element)tags.item(i);
			if(tagElement.getTagName().equals(TAG_ELEMENT)) {
				file.add(deserializeTag(tagElement));
			}
		}
		
		return file;
		// end-user-code
	}

	/** 
	 * <!-- begin-UML-doc -->
	 * <!-- end-UML-doc -->
	 * @param object
	 * @return
	 */
	protected Tag deserializeTag(Element element) {
		// begin-user-code
		Tag tag = new Tag();
		tag.setName(element.getAttribute(NAME_ATTRIBUTE));
		return tag;
		// end-user-code
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
}